package ru.jexp.rcp.supply.viewer.search;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;

import ru.jexp.rcp.supply.img.JExpImageLink;
import ru.jexp.rcp.supply.mui.JExpSupplyMessages;
import ru.jexp.rcp.supply.swtext.JExpText;
import ru.jexp.rcp.supply.swtext.factory.JExpControlFactory;
import ru.jexp.rcp.supply.swtext.factory.JExpLayoutFactory;
import ru.jexp.rcp.supply.viewer.JExpTableLabelProvider;

public class JExpSearchPanel implements ModifyListener {

	private JExpText text;
	private ColumnViewer viewer;
	private FilterBar filter;

	private class FilterText extends ViewerFilter {
		@Override
		public boolean select(Viewer viewer, Object parentElement,
				Object element) {
			if (filter.getSelectionColumns().isEmpty()
					|| text.getValue().isEmpty()) {
				return true;
			}
			for (int i = 0; i < getLabelProvider(viewer).getColumnsSize(); i++) {
				String curColumnName = getLabelProvider(viewer)
						.getColumnName(i);
				if (filter.getSelectionColumns().contains(curColumnName)) {
					if (getLabelProvider(viewer).getColumnText(element, i)
							.toLowerCase().indexOf(
									text.getValue().toLowerCase()) != -1) {
						return true;
					}
				}
			}
			return false;
		}

		private JExpTableLabelProvider getLabelProvider(Viewer viewer) {
			return (JExpTableLabelProvider) ((ColumnViewer) viewer)
					.getLabelProvider();
		}
	}

	public JExpSearchPanel(Composite parent) {
		text = JExpControlFactory.createText(parent);
		text.setLayoutData(JExpLayoutFactory.gdWithSizeHorizontal(300));
		text.setHintMessage(JExpSupplyMessages.Global_search_hint);
		ToolBarManager tool = new ToolBarManager();
		filter = new FilterBar();
		tool.add(filter);
		tool.createControl(parent);
	}

	public void setViewer(ColumnViewer viewer) {
		this.viewer = viewer;
		filter.setViewer(viewer);
		text.addModifyListener(this);
		viewer.addFilter(new FilterText());
	}

	public void setFocus()
	{
		text.setFocus();
	}
	
	@Override
	public void modifyText(ModifyEvent e) {
		viewer.refresh();
	}

	private static class FilterAction extends Action {

		private final FilterBar filter;

		public FilterAction(String text, FilterBar filter) {
			super(text, IAction.AS_CHECK_BOX);
			this.filter = filter;
		}

		@Override
		public void run() {
			if (isChecked()) {
				filter.putSelectionColumn(getText());
			} else {
				filter.removeSelectionColumn(getText());
			}
			filter.viewer.refresh();
		}
	}

	private static class FilterBar extends Action implements IMenuCreator {

		private ColumnViewer viewer;
		private Set<String> selectionColumns;

		public FilterBar() {
			super(null, IAction.AS_DROP_DOWN_MENU);
			setMenuCreator(this);
			setImageDescriptor(JExpImageLink
					.getImageDescriptor(JExpImageLink.SEARCH));
			selectionColumns = new HashSet<String>();
		}

		public void removeSelectionColumn(String text) {
			getSelectionColumns().remove(text);
		}

		public Set<String> getSelectionColumns() {
			return selectionColumns;
		}

		public void putSelectionColumn(String column) {
			selectionColumns.add(column);
		}

		public void setViewer(ColumnViewer viewer) {
			this.viewer = viewer;
			if (viewer.getLabelProvider() instanceof JExpTableLabelProvider) {
				JExpTableLabelProvider provider = (JExpTableLabelProvider) viewer
						.getLabelProvider();
				for (int i = 0; i < provider.getColumnsSize(); i++) {
					selectionColumns.add(provider.getColumnName(i));
				}
			}
		}

		@Override
		public void dispose() {
		}

		@Override
		public Menu getMenu(Control parent) {
			if (viewer == null) {
				throw new IllegalArgumentException("viewer is null");
			}
			if (viewer.getLabelProvider() instanceof JExpTableLabelProvider) {
				JExpTableLabelProvider label = (JExpTableLabelProvider) viewer
						.getLabelProvider();
				Menu menu = new Menu(parent);
				for (int i = 0; i < label.getColumnsSize(); i++) {
					FilterAction filterAction = new FilterAction(label
							.getColumnName(i), this);
					filterAction.setChecked(getSelectionColumns().contains(
							label.getColumnName(i)));
					ActionContributionItem contribution = new ActionContributionItem(
							filterAction);
					contribution.fill(menu, menu.getItemCount());
				}
				return menu;
			}
			return null;
		}

		@Override
		public Menu getMenu(Menu parent) {
			return null;
		}
	}
}
